package com.codeoss.module.purchase.service.impl;

import java.math.BigDecimal;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.codeoss.framework.service.impl.BaseService;
import com.codeoss.module.account.model.AccountTax;
import com.codeoss.module.account.service.IAccountTaxService;
import com.codeoss.module.purchase.dao.PurchaseOrderMapper;
import com.codeoss.module.purchase.model.PurchaseOrder;
import com.codeoss.module.purchase.model.PurchaseOrderLine;
import com.codeoss.module.purchase.service.IPurchaseOrderLineService;
import com.codeoss.module.purchase.service.IPurchaseOrderService;
import com.codeoss.module.stock.model.StockLocator;
import com.codeoss.module.stock.service.IStockLocatorService;
import com.codeoss.module.stock.service.IStockStorageService;

@Service
public class PurchaseOrderService extends BaseService<PurchaseOrderMapper, PurchaseOrder>
		implements IPurchaseOrderService {

	@Autowired
	private IPurchaseOrderLineService purchaseOrderLineService;
	@Autowired
	private IAccountTaxService accountTaxService;
	@Autowired
	private IStockStorageService stockStorageService;
	@Autowired
	private IStockLocatorService stockLocatorService;
	@Override
	public BigDecimal calculateAmountTotal(Long id) {
		// TODO Auto-generated method stub
		QueryWrapper<PurchaseOrderLine> lineQuery = new QueryWrapper<PurchaseOrderLine>();
		lineQuery.eq("purchase_order_id", id);
		List<PurchaseOrderLine> lineList = purchaseOrderLineService.list(lineQuery);
		BigDecimal amountTotal = new BigDecimal(0);
		for (PurchaseOrderLine line : lineList) {
			BigDecimal subTotal = line.getAmountSubtotal();
			if (subTotal != null) {
				amountTotal = amountTotal.add(subTotal);
			}
		}
		return amountTotal;
	}

	@Override
	public BigDecimal calculateAmountUntaxed(Long id) {
		// TODO Auto-generated method stub
		QueryWrapper<PurchaseOrderLine> lineQuery = new QueryWrapper<PurchaseOrderLine>();
		lineQuery.eq("purchase_order_id", id);
		List<PurchaseOrderLine> lineList = purchaseOrderLineService.list(lineQuery);
		BigDecimal amountUntaxed = new BigDecimal(0);
		for (PurchaseOrderLine line : lineList) {
			BigDecimal qtyOrdered = line.getQtyOrdered();
			BigDecimal total = qtyOrdered.multiply(line.getPriceEntered());
			amountUntaxed = amountUntaxed.add(total);
		}
		return amountUntaxed;
	}

	@Override
	public BigDecimal calculateAmountTax(Long id) {
		// TODO Auto-generated method stub
		QueryWrapper<PurchaseOrderLine> lineQuery = new QueryWrapper<PurchaseOrderLine>();
		lineQuery.eq("purchase_order_id", id);
		List<PurchaseOrderLine> lineList = purchaseOrderLineService.list(lineQuery);
		BigDecimal amountTax = new BigDecimal(0);
		for (PurchaseOrderLine line : lineList) {
			Long taxId = line.getAccountTaxId();
			BigDecimal qtyOrdered = line.getQtyOrdered();
			BigDecimal total = qtyOrdered.multiply(line.getPriceEntered());
			AccountTax accountTax = accountTaxService.getById(taxId);
			BigDecimal accountRate = accountTax.getRate().divide(new BigDecimal(100));
			amountTax = amountTax.add(total.multiply(accountRate));
		}
		return amountTax;
	}

	@Override
	@Transactional
	public void prepareIt(Long id) {
		// TODO Auto-generated method stub
		List<PurchaseOrderLine> purchaseOrderLineList=purchaseOrderLineService.getLineListByPurchaseOrderId(id);
		if(purchaseOrderLineList==null ||purchaseOrderLineList.size()==0 ) {
			throw new RuntimeException("没有行明细");
		}
	}

	@Override
	@Transactional
	public void approveIt(Long id) {
		// TODO Auto-generated method stub
		PurchaseOrder purchaseOrder=getById(id);
		purchaseOrder.setApproved(true);
		update(purchaseOrder);
	}

	@Override
	@Transactional
	public void rejectIt(Long id) {
		// TODO Auto-generated method stub
		PurchaseOrder purchaseOrder=getById(id);
		purchaseOrder.setApproved(false);
		update(purchaseOrder);
	}

	@Override
	@Transactional
	public void completeIt(Long id) {
		// TODO Auto-generated method stub
		PurchaseOrder purchaseOrder=getById(id);
		purchaseOrder.setDocStatus("CO");
		update(purchaseOrder);
		if(!purchaseOrder.getApproved()) {
			return;
		}
		List<PurchaseOrderLine> purchaseOrderLineList=purchaseOrderLineService.getLineListByPurchaseOrderId(id);
		orderStock(purchaseOrder,purchaseOrderLineList);
	}

	protected void orderStock(PurchaseOrder purchaseOrder,List<PurchaseOrderLine> purchaseOrderLineList) {
		StockLocator stockLocator=stockLocatorService.getDefaultLocator(purchaseOrder.getStockWarehouseId());
		for(int i=0;i<purchaseOrderLineList.size();i++) {
			PurchaseOrderLine purchaseOrderLine=purchaseOrderLineList.get(i);
			purchaseOrderLine.setQtyReserved(purchaseOrderLine.getQtyOrdered());
			purchaseOrderLineService.update(purchaseOrderLine);
			stockStorageService.add(purchaseOrder.getStockWarehouseId(), stockLocator.getId(), purchaseOrderLine.getProductProductId(), 
					purchaseOrderLine.getProductAttrSetInstanceId(), new BigDecimal(0),new BigDecimal(0), purchaseOrderLine.getQtyOrdered());
		}
	}
	
	@Override
	public void setDocStatus(Long id, String docStatus) {
		// TODO Auto-generated method stub
		PurchaseOrder purchaseOrder=getById(id);
		purchaseOrder.setDocStatus(docStatus);
		update(purchaseOrder);
	}

}